#include "ThresholdAction.h"
#include "Layer.h"
#include "Work.h"

ThresholdAction::ThresholdAction (Ptr< AbstractThreshold > thresholdMethod,
        Ptr< Work > pTargetWork) : AbstractAction (pTargetWork), 
        _thresholdMethod (thresholdMethod)
{

}



void ThresholdAction::updatePreview (QRect viewport)
{
  Ptr< Layer > pCurLayer = __pTargetWork->getDoc ()->getCurrentLayer ();

  bool isPreview = true;
  if (viewport.isEmpty ()) {
    isPreview = false;
    viewport = pCurLayer->getRegion ();
  }

  QRect updateRegion = viewport & pCurLayer->getRegion ();
  
  QPoint oSrcImg = pCurLayer->getRegion ().topLeft ();
  QPoint oViewport = viewport.topLeft ();
  QPoint oUpdate = updateRegion.topLeft ();
  
  QRect processRegion = updateRegion;
  processRegion.translate (-oSrcImg);

  Ptr< QImage > pProcessSrc = new QImage (
          pCurLayer->getImage ()->copy (processRegion));
  Ptr< QImage > pProcessResult = _thresholdMethod->process (pProcessSrc);

  // Draw preview image
//   Ptr< QImage > pPreview = new QImage (viewport.size (), 
//           QImage::Format_ARGB32);
//   pPreview->fill (0);
// 
//   for (int v = updateRegion.top (); v <= updateRegion.bottom (); ++v)
//   {
//     QRgb * previewLine = (QRgb *)pPreview->scanLine (v - oViewport.y ());
//     QRgb * resultLine = (QRgb *)pProcessResult->scanLine (v - oUpdate.y ());
//     memcpy (&resultLine[updateRegion.left () - oViewport.x ()], resultLine, 
//             updateRegion.width () * sizeof (QRgb));
//   }

  if (isPreview)
    pCurLayer->setPreviewImage (pProcessResult);
  else
    pCurLayer->setImage (pProcessResult);

}



void ThresholdAction::rejectAction ()
{
  __pTargetWork->getDoc ()->getCurrentLayer ()->closePreview ();
}



void ThresholdAction::handleStartEvent ()
{
  __pTargetWork->getDoc ()->getCurrentLayer ()->openPreview ();
}



void ThresholdAction::applyAction ()
{
  updatePreview (QRect ());
  __pTargetWork->getDoc ()->getCurrentLayer ()->closePreview ();
}



void ThresholdAction::setThresholdMethod (
        Ptr< AbstractThreshold > thresholdMethod)
{
  _thresholdMethod = thresholdMethod;
}